#include "IntroUtil.fx"

uniform float gTime;

#define NO_INTERSECTION 9999999.0f
#define EPS             0.0001f

#define MATERIAL_BOX 1
#define MATERIAL_PLANE 2
#define MATERIAL_SPHERE 3

uniform float3 gTexPos;

float distFunc(float3 P, out int materialID)
{
	float sphere1 = 1.0f;
	float3 box1size = float3(2.0f, 0.5f, 0.5f);
	
	float3 inputPos;
	
	inputPos = P;
	float distPlane = distancePlane(inputPos);
	
	inputPos = P;
	
	//inputPos.xy=rotSph(inputPos.xy,4);
	//inputPos.xz=rotSph(inputPos.xz, 2);

	inputPos += float3(0,-3,0);
	float freq = 5.0f;
	float ampl = 0.02f;
	inputPos += inputPos * perlin(freq * inputPos) * ampl;
	float distBox = distanceBox(inputPos, box1size);
	float distSphere = distanceSphere(inputPos, sphere1);
	
	float blendFac = (sin(gTime)) * 0.5f + 0.5f;
	float distBlend = blendFac * distBox + (1 - blendFac) * distSphere;
	
	float dist = distPlane;
	materialID = MATERIAL_PLANE;
	

	if(distBlend < dist)
	{
		dist = distBlend;
		materialID = MATERIAL_SPHERE;
	}
	
	return dist;
}

float distFunc4(float3 P, out int materialID)
{
	float sphere1 = 1.0f;
	float3 box1size = float3(2.0f, 0.5f, 0.5f);
	
	float3 inputPos;
	
	inputPos = P;
	float distPlane = distancePlane(inputPos);
	
	inputPos = P;
	
	//inputPos.xy=rotSph(inputPos.xy,4);
	//inputPos.xz=rotSph(inputPos.xz, 2);
	
	float posR = length(inputPos);
	float th = asin(inputPos.y / posR);
	float ph = atan2(inputPos.z, inputPos.x);
	ph = (ph - PI) % (PI * 0.5f);
	inputPos.x = posR * cos(ph) * cos(th);
	inputPos.z = posR * sin(ph) * cos(th);
	inputPos.y = posR * sin(th);

	inputPos += float3(-5,-1,2.5f);
	//float freq = 10.0f * (sin(gTime));
	//float ampl = 0.04f * (sin(gTime));
	//inputPos += inputPos * perlin(freq * inputPos) * ampl;
	float distSphere1 = distanceBox(inputPos, box1size);

	
	float dist = distPlane;
	materialID = MATERIAL_PLANE;
	

	if(distSphere1 < dist)
	{
		dist = distSphere1;
		materialID = MATERIAL_SPHERE;
	}
	
	return dist;
}

float distFunc3(float3 P, out int materialID)
{
	float2 torus1 = float2(1.0f, 0.2f);
	float sphere1 = 1.0f;
	float3 inputPos;
	
	float freq = 10.0f;
	float ampl = 0.04f;
	
	
	inputPos = P;
	float distPlane = distancePlane(inputPos);
	
	inputPos = P;
	inputPos.y -= 5.0f;
	inputPos += inputPos * perlin(freq * inputPos) * ampl;
	float distSphere1 = distanceSphere(inputPos, sphere1);
	
	inputPos = P;
	inputPos.y -= 5.0f;
	inputPos.z += sin(gTime) * 4.0f;
	inputPos += inputPos * perlin(freq * inputPos) * ampl;
	inputPos.xz = Rotate(inputPos.xz, 3.14f * 0.5f);
	float distSphere2 = distanceSphere(inputPos, sphere1);
	
	
	float srf = 1.0f /(distSphere1 + 0.5f + EPS) + 1.0f / (distSphere2 + 0.5f + EPS);
	float dsrf = 1.0f / srf - 0.5f;
	
	
	float dist = distPlane;
	materialID = MATERIAL_PLANE;
	

	if(dsrf < dist)
	{
		dist = dsrf;
		materialID = MATERIAL_BOX;
	}
	
	return dist;
}

float distFunc2(float3 P, out int materialID)
{
	float sphere1 = 4.0f;
	float3 box1size = float3(6.0f, 0.5f, 0.5f);
	float4 roubox1size = float4(2.0f, 2.0f, 2.0f, 1.5f);

	P = float3(P.x % 20.0f - 10.0f, P.y, P.z % 20.0f - 10.0f);
	//float3 modPos = float3(currPos.x % 15.0f, currPos.y, currPos.z % 15.0f);
	/*
	float3 modPos = float3(currPos.x, currPos.y, currPos.z);
	float dist = distSphere(modPos, sphere1);
	if(dist < EPS)
	{
		pixelColor = float3(0.3f, 0.5f, 1.0f) * lighting(currPos, normalize(modPos - sphere1.xyz));
		break;
	}
	*/
	float3 inputPos = P;
	inputPos.y -= 4.0f;
	inputPos.yx = Rotate(inputPos.yx, sin(gTime * 4.0f) * inputPos.x * 0.05f);
	float twistMid = frac(gTime) * 1.2f - 0.1f;
	float twistPos = 5.0f * ((inputPos.x / 12.0f + 0.5f) - twistMid + 0.1f);
	//float twistAmount = lerp(0.0f, 1.0f, twistPos);
	inputPos.yz = Rotate(inputPos.yz, (twistPos < 1.0f && twistPos > 0.0f) ? 3.14f * (1.0f - twistPos) : 0.0f);
	float distTwistedBox;
	distTwistedBox = distanceBox(inputPos, box1size);
	
	inputPos = P;
	float distPlane = distancePlane(inputPos);
	
	float distSphere = distanceRouBox(P + float3(0,-4,0), roubox1size);
	
	float dist = distTwistedBox;
	materialID = MATERIAL_BOX;
	
	if(distPlane < dist)
	{
		dist = distPlane;
		materialID = MATERIAL_PLANE;
	}
	if(distSphere < dist)
	{
		dist = distSphere;
		materialID = MATERIAL_SPHERE;
	}
	
	return dist;
}
